﻿using Opc.Ua.Configuration;
using SD.Infrastructure;
using SD.OpcServer.Host.Hosts;
using SD.OpcServer.Host.Variables;
using SD.OpcServer.Models.Base;
using SD.OpcServer.Models.Entities;
using System.Collections.Generic;
using System.Linq;

namespace SD.OpcServer.Host
{
    /// <summary>
    /// OPC服务启动器
    /// </summary>
    public static class Startup
    {
        /// <summary>
        /// 配置服务
        /// </summary>
        /// <param name="opcApplication">OPC应用实例</param>
        public static void ConfigureServices(ApplicationInstance opcApplication)
        {
            //加载配置
            opcApplication.LoadApplicationConfiguration(Constants.OpcServerConfigPath, false);

            //认证配置
            opcApplication.CheckApplicationInstanceCertificate(false, 0);

            //配置变量
            ICollection<OpcVariableGroup> variableGroups = ConfigureVariables();

            //启动服务
            OpcServiceHost serviceHost = new OpcServiceHost(variableGroups);
            opcApplication.Start(serviceHost);
        }

        /// <summary>
        /// 配置变量
        /// </summary>
        private static ICollection<OpcVariableGroup> ConfigureVariables()
        {
            ICollection<OpcVariableGroup> opcVariableGroups = new HashSet<OpcVariableGroup>();
            OpcVariableGroup opcVariableGroup = new OpcVariableGroup(FrameworkSection.Setting.ApplicationName.Value, null);
            IList<OpcVariable> opcVariables = new List<OpcVariable>();

            using (DbSession dbSession = new DbSession())
            {
                IList<Variable> variables = dbSession.Set<Variable>().ToList();
                foreach (Variable variable in variables)
                {
                    OpcVariable opcVariable = new OpcVariable(variable.Number, variable.Name, variable.DataType, variable.Unit, variable.KeepRecord, $"{variable.Name}|{variable.Description}", variable.ValueDescriptions, opcVariableGroup);
                    opcVariables.Add(opcVariable);
                    variable.SetNodeId(opcVariable.NodeId.ToString());
                }

                opcVariableGroup.Variables = opcVariables;
                opcVariableGroups.Add(opcVariableGroup);

                dbSession.SaveChanges();
            }

            return opcVariableGroups;
        }
    }
}
